﻿(function($, $$){
	$$.widget = $$.extend($$, function(){
		console.debug(this.parent);
	});
	
	console.debug($$.widget());
})(jQuery, jkui);

(function($){
	if (typeof jkui == 'undefined')
		jkui = {};
	
	jkui.dialog = function(jDom, o){
		
		$(jDom).each(function(){
			init.call(jDom, o);
		});
		
	}
	
	jkui.dialog.prototype = {
		init: function (o) {
			if ($.dialog.modalInstances)
				return false;
				
			var defaultOptions = {
				width: 500,
				morphStart: null,
				modal: true,
				buttons: [{'class': 'ok', 'caption': 'OK'}, {'class': 'cancel', 'caption': 'Cancel'}],
				ok: function(){},
				cancel: function(){},
				load: function(){},
				loaded: function(){}
			};
			
			o = $.extend (defaultOptions, o);
			
			for (var i = 0; i < o.buttons.length; i++){
				if (typeof o[o.buttons[i]['class']] == 'undefined')
					o[o.buttons[i]['class']] = function(){};
			}
			
			var dialog = $.dialog.build.call($(this), o);
			$.dialog.bindEvents.call(dialog, o);
			
			o.load.call(dialog);
			
			return dialog;
		},
		build: function(o){
			if (o.modal){
				$.dialog.modalInstances ++;
				$('body').append($('<div class="background_cover"></div>').css('opacity', 0.2).height($(document).height()));
			}
			
			var dialogBackground = $('<div class="dialog_background"></div>').appendTo('body');
			
			var dialog = $('<div class="dialog"><h3 class="dialog_title">'+o.title+'</h3></div>').css({
				top:0,
				left: ($('body').width() - 20 - o.width) / 2,
				width: o.width,
				position: 'absolute',
				visibility: 'hidden'
			}).append(this.clone(true)).append('<ul class="dialog_actions"></ul>');
			
			var actions = dialog.find('ul.dialog_actions');
			for (var i = o.buttons.length - 1; i >= 0; i--)
				actions.append('<li><a href="#" class="' + o.buttons[i]['class'] + '">'+o.buttons[i]['caption'] + '</a></li>');
			
			dialog.appendTo('body').css('top', $(document).scrollTop() + ($(window).height() - 20 - dialog.height()) / 2);
		
			dialogBackground.css({
				top: dialog.offset().top - 10,
				left: dialog.offset().left - 10,
				height: dialog.outerHeight() + 20,
				width: dialog.outerWidth() + 20,
				visibility: 'hidden'
			});
			
			//this is the interface returned to callers defined by user
			var ret = {
				dialog: dialog,
				background: dialogBackground,
				adjust: function(){
					dialogBackground.height(dialog.height()+30);
				},
				trigger: function(name, params){
					if (arguments.length > 2) {
						params = Array.apply(arguments);
						params.shift();
					} else if(arguments.length == 2 && !(arguments[1] instanceof Array)) 
						params = [params];
						
					if (typeof o.dialogEvents[name] == 'function'){
						o.dialogEvents[name].apply(this, params);
					} else if (typeof o[name] == 'function'){
						o[name].apply(this, params);
					}
				}
			};
			
			var morphling = null;
			if (o.morphStart) {
				o.morphStart = $(o.morphStart);
				var rect = $.extend (o.morphStart.offset(), {width: o.morphStart.width(), height: o.morphStart.height(), opacity:0.5});
				morphling = $('<div class="dialog_morphling">').css(rect).css('position', 'absolute').appendTo('body');

				//TODO: define morphling's end behavior
				morphling.animate($.extend({width: dialogBackground.width(), height: dialogBackground.height()},dialogBackground.offset()), 300, function(){
					$(this).remove();
					dialog.css({'visibility':'inherit','opacity':0.5}).animate({'opacity':1},300, function(){
						o.loaded.call(ret);
					});
					dialogBackground.css('visibility','visible');
				});
			} else{
				dialog.css({'visibility':'inherit','opacity':0.5}).animate({'opacity':1},300, function(){
					o.loaded.call(ret);
				});
				dialogBackground.css('visibility','visible');
			}
			
			return ret;
		},
		bindEvents: function(o){
			var dialog = this;
			function eventBuilder (name){
				return function(){
					if (typeof o[name] != 'function'){
						$.dialog.unload.call(dialog, o)();
						return false;
					}
					
					//if the event handler is in a callback form
					if (o[name].length)
						o[name].call(dialog, $.dialog.unload.call(dialog, o));
					else{
						o[name].call(dialog);
						$.dialog.unload.call(dialog, o)();
					}
					return false;
				};
			};
			
			o.dialogEvents = {};
			
			$(this.dialog).find('ul.dialog_actions li a').each(function(){
				var me = $(this);
				var eventName = me.attr('class');
				o.dialogEvents[eventName] = eventBuilder(eventName);
				me.click(o.dialogEvents[eventName]);
			});
			
			$('div.background_cover').click(eventBuilder('cancel'));
		},
		unload: function(o){
			var dialog = this;
			
			return function(){
				$('div.background_cover').remove();
				
				if (o.morphStart instanceof $){
					dialog.dialog.animate({opacity:0}, 300, function(){
						dialog.background.animate($.extend(o.morphStart.offset(), {height: o.morphStart.height(), width: o.morphStart.width()}), 300,
							function(){$(this).remove();});
						$(this).remove();
					});
				} else
					$.each([dialog.background, dialog.dialog], function(){
						this.remove();
					});
				
				if (o.modal)
					$.dialog.modalInstances --;
			}
		},
		modalInstances: 0
	};
	
	//////////////////////// tab dialogs /////////////////////////
	
	$.fn.tabDialog = function(o){
		return this.each(function(){
			var me = $(this);
			
			var tab = o.display;
			if (tab instanceof Array)
				tab = tab[i];
			else if (typeof tab == 'undefined')
				tab = 0;
			
			if (typeof tab == 'string'){
				me.find('.tabs>div').hide();
				me.find('.tabs>div ' + tab).show();
			} else if (typeof tab == 'number') {
				me.find('.tabs>div').hide();
				me.find('.tabs>div:eq(' + tab + ')').show();
			} 
			
			var dialog = $.dialog.init.call(this, o);

			if (!dialog)
				return;
			
			var tabContent = dialog.dialog.find('.tabs').children('div').addClass('dialog_tab_content');
			
			dialog.dialog.find('.tabs>ul>li').each(function(i){
				$(this).click(function(){
					$(this).find('a').addClass('active').end()
							.siblings().each(function(){$(this).find('a').removeClass('active');});
					tabContent.hide();
					$(tabContent[i]).show();
					dialog.background.height(dialog.dialog.height() + 30);
					return false;
				});
			});
			
			if (typeof tab == 'string'){
				dialog.dialog.find('.tabs>ul ' + tab).click();
			} else if (typeof tab == 'number') {
				dialog.dialog.find('.tabs>ul>li>a:eq(' + tab + ')').click();
			}
		});
	}
	
})(jQuery);

$('.info a.edit_info').click(function(){
	$('#components .editor').tabDialog({
		morphStart: '.info',
		title: 'Edit',
		width:500,
		display: 0
	});
	return false;
});

$('.tags a.edit_tags').click(function(){
	$('#components .editor').tabDialog({
		morphStart: '.tags',
		title: 'Edit',
		display: 1
	});
	return false;
});

$('.top_bar a.login').click(function(){
	$('#components .login').dialog({
		morphStart: this,
		title: 'Login/Register',
		width: 350,
		load: function(){
			var me = this;
			this.dialog.find('form[name=login] input[name=username]').change(function(){
				$(this).parents('form').next('form').removeClass('hide').find('input[name=username]').focus().end().end()
						.addClass('hide');
				me.adjust();
			});
		},
		loaded: function(){
			this.dialog.find('form[name=login] input[name=username]').focus();
		}
	});
});
